﻿/**************************************************
* 版权所有:Copyright (C) 
* 作    者:蔡海翔
* 创建日期:2014/6/16 13:36:19
* 描    述:
* 修改日期:
* 修改内容:
****************************************************/

using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.Threading.Tasks;
using IntelligentQuery.Extensions;
using IntelligentQuery.Model;
using System.Web;
namespace DataAccess
{
    public class EntityRepository<TEntity> : IEntityRepository<TEntity> where TEntity : class
    {
        internal DataContext context;
        internal DbSet<TEntity> dbSet;
        //public EntityRepository()
        //    : this(new DataContext())
        //{
        //}
        public EntityRepository(DataContext context)
        {
            this.context = context;
            this.dbSet = context.Set<TEntity>();
        }
        /// <summary>
        /// 获得实体集合
        /// </summary>
        /// <param name="filter"></param>
        /// <param name="orderBy"></param>
        /// <param name="includeProperties"></param>
        /// <returns></returns>
        public IQueryable<TEntity> Get(Expression<Func<TEntity, bool>> filter = null, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
        {
            IQueryable<TEntity> query = dbSet.AsNoTracking();
            if (filter != null)
            {
                query = query.Where(filter);
            }
            foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }
            if (orderBy != null)
            {
                return orderBy(query);
            }
            else
            {
                return query;
            }
        }
        public IQueryable<TEntity> Get(QueryModel model, Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null, string includeProperties = "")
        {
            IQueryable<TEntity> query = dbSet.AsNoTracking();
            if (model != null)
            {
                query = query.Where(model);
            }
            foreach (var includeProperty in includeProperties.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
            {
                query = query.Include(includeProperty);
            }
            if (orderBy != null)
            {
                return orderBy(query);
            }
            else
            {
                return query;
            }
        }
        /// <summary>
        /// 根据实键值获得单个实体
        /// </summary>
        /// <param name="Key"></param>
        /// <returns></returns>
        public TEntity GetByKey(params object[] Key)
        {
            return dbSet.Find(Key);
        }
        /// <summary>
        /// 插入单个实体
        /// </summary>
        /// <param name="entity"></param>
        public void Insert(TEntity entity)
        {
            dbSet.Add(entity);
            SaveChanges();
        }
        /// <summary>
        /// 插入实体集合
        /// </summary>
        /// <param name="list"></param>
        public void Insert(IList<TEntity> list)
        {
            context.Configuration.AutoDetectChangesEnabled = false;
            //foreach (TEntity entity in list)
            //{
            //    context.Set<TEntity>().Attach(entity);
            //    context.Entry<TEntity>(entity).State = EntityState.Added;
            //}
            list.ToList().ForEach(entity =>
            {
                dbSet.Attach(entity);
                context.Entry(entity).State = EntityState.Added;
            });
            //list.ToList().ForEach(entity => dbSet.Add(entity));
            context.Configuration.AutoDetectChangesEnabled = true;
            SaveChanges();
        }
        /// <summary>
        /// 根据主键值删除单个实体
        /// </summary>
        /// <param name="Key"></param>
        public void Delete(params object[] Key)
        {
            TEntity entityToDelete = dbSet.Find(Key);
            Delete(entityToDelete);
        }
        /// <summary>        
        /// 删除单个实体       
        /// </summary>
        public void Delete(TEntity entity)
        {
            if (context.Entry(entity).State == EntityState.Detached)
            {
                dbSet.Attach(entity);
            }
            dbSet.Remove(entity);
            SaveChanges();
        }
        /// <summary>
        /// 删除实体集合
        /// </summary>
        /// <param name="list"></param>
        public void Delete(IList<TEntity> list)
        {
            context.Configuration.AutoDetectChangesEnabled = false;
            list.ToList().ForEach(entity =>
            {
                if (context.Entry(entity).State == EntityState.Detached)
                {
                    dbSet.Attach(entity);
                }
                dbSet.Remove(entity);
            });
            context.Configuration.AutoDetectChangesEnabled =true;
            SaveChanges();
        }
        /// <summary>
        /// 更新单个实体
        /// </summary>
        /// <param name="entity"></param>
        public void Update(TEntity entity)
        {
            dbSet.Attach(entity);
            context.Entry(entity).State = EntityState.Modified;
            SaveChanges();
        }
        /// <summary>
        /// 更新实体集合
        /// </summary>
        /// <param name="list"></param>
        public void Update(IList<TEntity> list)
        {
            context.Configuration.AutoDetectChangesEnabled = false;
           
            list.ToList().ForEach(entity =>
            {
                dbSet.Attach(entity);
                context.Entry(entity).State = EntityState.Modified;
            });
            
            context.Configuration.AutoDetectChangesEnabled = true;
            SaveChanges();
        }
        public IEnumerable<TEntity> GetWithRawSql(string query, params object[] parameters)
        {
            return dbSet.SqlQuery(query, parameters);
        }
        public IEnumerable<TEntity> GetwhithdbSql(string query, params object[] parameters)
        {
            return context.Database.SqlQuery<TEntity>(query, parameters);
        }
        public int ExecSqlCommand(string sql, params object[] parameters)
        {
            return context.Database.ExecuteSqlCommand(sql, parameters);
        }
        /// <summary>
        /// 得到当年用户名
        /// </summary>
        /// <returns></returns>
        public string GetCurrentUserNo()
        {
            if (!string.IsNullOrEmpty(HttpContext.Current.Request.Cookies["UserName"].Value))
            {
                return HttpContext.Current.Request.Cookies["UserName"].Value;

            }
            else
            {
                return "admin";
            }
        }
        public int SaveChanges()
        {
            foreach (var entry in context.ChangeTracker.Entries().Where(e => e.Entity is DataEntity.SysLogBaseField && (e.State == EntityState.Added | e.State == EntityState.Modified)))
            {
                var dateClass = (DataEntity.SysLogBaseField)entry.Entity;
                if (entry.State == EntityState.Added)
                {
                    dateClass.CreateDate = DateTime.Now;
                    dateClass.LastModifyDate = null;
                    dateClass.CreateUserName = GetCurrentUserNo();
                }
                if (entry.State == EntityState.Modified)
                {
                    dateClass.LastModifyDate = DateTime.Now;
                    dateClass.LastModifyUserName = GetCurrentUserNo();
                }
            }
            if (context.GetValidationErrors().Count() == 0)
            {
                return context.SaveChanges();
            }
            else
            {
                return -1;
            }
        }
       
        
        
    }
}
